﻿//++
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Module Name:
//
//    TimeControlTest.cs
//
// Abstract:
//    
//    Unit tests for the time control.
//
// Classes:
//
//    Microsoft.EnhancedReminders.OutlookAddIn.UnitTests.TimeControlUnitTest
//
//--

using System;
using System.Windows.Controls;
using Microsoft.OfficeCommunicationsServer.Applications.Common;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Microsoft.EnhancedReminders.OutlookAddIn.UnitTests
{    
    /// <summary>
    ///This is a test class for StatusControlTest and is intended
    ///to contain all StatusControlTest Unit Tests
    ///</summary>
    [TestClass()]
    public class StatusControlTest
    {
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        /// <summary>
        /// Test that the status control is correctly initialized.
        ///</summary>
        [TestMethod()]
        public void InitializeTest()
        {
            StatusControl_Accessor accessor = new StatusControl_Accessor();

            NotificationStatusCondition statusCondition = new NotificationStatusCondition();

            statusCondition.Presence = 
                PresenceStates.BeRightBack | 
                PresenceStates.DoNotDisturb | 
                PresenceStates.IdleBusy;

            accessor.Initialize(statusCondition);

            // Verify each checkbox is correctly checked/unchecked and enabled.

            VerifyCheckbox(accessor.checkBoxAvailable, Properties.Resources.PresenceStateAvailable, PresenceStates.Available, /*isChecked*/false, /*isEnabled*/true);

            VerifyCheckbox(accessor.checkBoxBusy, Properties.Resources.PresenceStateBusy, PresenceStates.Busy, /*isChecked*/false, /*isEnabled*/true);

            VerifyCheckbox(accessor.checkBoxMeeting, Properties.Resources.PresenceStateInAMeeting, PresenceStates.InAMeeting, /*isChecked*/false, /*isEnabled*/true);

            VerifyCheckbox(accessor.checkBoxCall, Properties.Resources.PresenceStateInACall, PresenceStates.InACall, /*isChecked*/false, /*isEnabled*/true);

            VerifyCheckbox(accessor.checkBoxConference, Properties.Resources.PresenceStateInAConference, PresenceStates.InAConference, /*isChecked*/false, /*isEnabled*/true);

            VerifyCheckbox(accessor.checkBoxDoNotDisturb, Properties.Resources.PresenceStateDoNotDisturb, PresenceStates.DoNotDisturb, /*isChecked*/true, /*isEnabled*/true);

            VerifyCheckbox(accessor.checkBoxBeRightBack, Properties.Resources.PresenceStateBeRightBack, PresenceStates.BeRightBack, /*isChecked*/true, /*isEnabled*/true);

            VerifyCheckbox(accessor.checkBoxAway, Properties.Resources.PresenceStateAway, PresenceStates.Away, /*isChecked*/false, /*isEnabled*/true);

            VerifyCheckbox(accessor.checkBoxInactive, Properties.Resources.PresenceStateIdleOnline, PresenceStates.IdleOnline, /*isChecked*/false, /*isEnabled*/true);

            VerifyCheckbox(accessor.checkBoxIdleBusy, Properties.Resources.PresenceStateIdleBusy, PresenceStates.IdleBusy, /*isChecked*/true, /*isEnabled*/true);

            VerifyCheckbox(accessor.checkBoxOffline, Properties.Resources.PresenceStateOffline, PresenceStates.Offline, /*isChecked*/false, /*isEnabled*/true);

            VerifyCheckbox(accessor.checkBoxUnknown, Properties.Resources.PresenceStateUnknown, PresenceStates.Unknown, /*isChecked*/false, /*isEnabled*/true);
        }

        /// <summary>
        /// Helper method to verify a checkbox label is correct.  This searches for the
        /// textblock instance of the checkbox content to determine the label.
        /// </summary>
        /// <param name="checkbox">The checkbox to validate.</param>
        /// <param name="expectedLabel">The expected label value.</param>
        /// <param name="expectedTag">The expected PresenceState tag.</param>
        /// <param name="isChecked">The expected value for the IsChecked property.</param>
        /// <param name="isEnabled">The expected value for the IsEnabled property.</param>
        private void VerifyCheckbox(CheckBox checkbox, string expectedLabel, PresenceStates expectedTag, bool isChecked, bool isEnabled)
        {
            Assert.IsNotNull(checkbox, "checkbox");
            Assert.IsFalse(String.IsNullOrEmpty(expectedLabel), "expectedLabel");

            // Verify IsEnabled and IsChecked properties.
            Assert.AreEqual(isEnabled, checkbox.IsEnabled, "Unexpected value for checkbox.IsEnabled");
            Assert.AreEqual(isChecked, checkbox.IsChecked.Value, "Unexpected value for checkbox.IsChecked");

            // Verify the Tag.
            Assert.IsNotNull(checkbox.Tag, "checkbox.Tag is not initialized");
            Assert.AreEqual(expectedTag, Helpers.AssertCast<PresenceStates>(checkbox.Tag), "Unexpected checkbox.Tag");

            // Find the text label and verify it is correct.
            DockPanel panel = (DockPanel)checkbox.Content;

            Assert.IsNotNull(panel, "panel");
            Assert.IsNotNull(panel.Children, "panel.Children");
            Assert.IsTrue(panel.Children.Count > 1, "panel.Children.Count");

            TextBlock textBlock = Helpers.AssertCast<TextBlock>(panel.Children[1]);
            Assert.AreEqual(expectedLabel, textBlock.Text, "Unexpected checkbox label");
        }
         
        /// <summary>
        /// Test checking status checkboxes adds states to the presence state list.
        ///</summary>
        [TestMethod()]
        public void SelectCheckboxTest()
        {
            StatusControl_Accessor accessor = new StatusControl_Accessor();

            NotificationStatusCondition statusCondition = new NotificationStatusCondition();

            Assert.AreEqual(PresenceStates.None, statusCondition.Presence, "Unexpected presence state");

            accessor.Initialize(statusCondition);

            // Check the "In a meeting" and "Offline" checkboxes to add these status values.
            StatusControl_Accessor.CheckBoxCommand.Execute(this, accessor.checkBoxMeeting);
            StatusControl_Accessor.CheckBoxCommand.Execute(this, accessor.checkBoxOffline);

            Assert.AreEqual(PresenceStates.InAMeeting | PresenceStates.Offline, statusCondition.Presence, 
                           "Presence states have not been updated correctly.");
        }

        /// <summary>
        /// Test unchecking status checkboxes removes states from the presence state list.
        ///</summary>
        [TestMethod()]
        public void UnselectCheckboxTest()
        {
            StatusControl_Accessor accessor = new StatusControl_Accessor();

            NotificationStatusCondition statusCondition = new NotificationStatusCondition();

            statusCondition.Presence = PresenceStates.IdleBusy | PresenceStates.InACall | PresenceStates.InAConference;

            accessor.Initialize(statusCondition);

            // Uncheck "Idle busy" and "In a call" checkboxes.
            StatusControl_Accessor.CheckBoxCommand.Execute(this, accessor.checkBoxIdleBusy);
            StatusControl_Accessor.CheckBoxCommand.Execute(this, accessor.checkBoxCall);

            Assert.AreEqual(PresenceStates.InAConference, statusCondition.Presence,
                            "Presence states have not been updated correctly.");
        }
    }
}
